﻿// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System;
using System.Text.Json;

namespace SnapObjects.Data
{
    internal static class SysJsonWriterHelper
    {
        public static void WriteJsonElement(INodeWriter writer, string propertyName, JsonElement element)
        {
            switch (element.ValueKind)
            {
                case JsonValueKind.Object:
                    WriteJsonObject(writer, propertyName, element);
                    break;
                case JsonValueKind.Array:
                    WriteJsonArray(writer, propertyName, element);
                    break;
                case JsonValueKind.String:
                    writer.WriteAsValue(propertyName).WriteValue(element.GetString());
                    break;
                case JsonValueKind.Number:
                    WriteJsonNumber(writer, propertyName, element);
                    break;
                case JsonValueKind.True:
                case JsonValueKind.False:
                    writer.WriteAsValue(propertyName).WriteValue(element.GetBoolean());
                    break;
                case JsonValueKind.Null:
                    writer.WriteAsValue(propertyName).WriteNull();
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }

        private static void WriteJsonObject(INodeWriter writer, string propertyName, JsonElement element)
        {
            writer.WriteAsObject(propertyName);

            foreach (var jsonProperty in element.EnumerateObject())
            {
                WriteJsonElement(writer, jsonProperty.Name, jsonProperty.Value);
            }

            writer.WriteEndObject();
        }

        private static void WriteJsonArray(INodeWriter writer, string propertyName, JsonElement element)
        {
            writer.WriteAsArray(propertyName);

            foreach (var jsonElement in element.EnumerateArray())
            {
                WriteJsonElement(writer, String.Empty, jsonElement);
            }

            writer.WriteEndArray();
        }

        private static void WriteJsonNumber(INodeWriter writer, string propertyName, JsonElement jsonProperty)
        {
            writer.WriteAsValue(propertyName);

            if (jsonProperty.TryGetSByte(out var sbyteValue))
            {
                writer.WriteValue(sbyteValue);
            }
            else if (jsonProperty.TryGetByte(out var byteValue))
            {
                writer.WriteValue(byteValue);
            }
            else if (jsonProperty.TryGetUInt16(out var ushortValue))
            {
                writer.WriteValue(ushortValue);
            }
            else if (jsonProperty.TryGetUInt32(out var uintValue))
            {
                writer.WriteValue(uintValue);
            }
            else if (jsonProperty.TryGetUInt64(out var ulongValue))
            {
                writer.WriteValue(ulongValue);
            }
            else if (jsonProperty.TryGetInt16(out var shortValue))
            {
                writer.WriteValue(shortValue);
            }
            else if (jsonProperty.TryGetInt32(out var intValue))
            {
                writer.WriteValue(intValue);
            }
            else if (jsonProperty.TryGetInt64(out var longValue))
            {
                writer.WriteValue(longValue);
            }
            else if (jsonProperty.TryGetDecimal(out var decValue))
            {
                writer.WriteValue(decValue);
            }
            else if (jsonProperty.TryGetSingle(out var floatValue))
            {
                writer.WriteValue(floatValue);
            }
            else if (jsonProperty.TryGetDouble(out var doubleValue))
            {
                writer.WriteValue(doubleValue);
            }
            else
            {
                writer.WriteValue(jsonProperty.GetString());
            }
        }
    }
}